home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / protocol / standard / network / utf / utf_code next >
Internet Message Format  |  1993-07-14  |  7KB

  1. From ISO10646@JHUVM.BITNET Wed Sep  4 02:03:48 1991
  2. Received: from danpost2.uni-c.dk by dkuug.dk via EUnet with SMTP (5.64+/8+bit/IDA-1.2.8)
  3.     id AA12183; Wed, 4 Sep 91 02:03:43 +0200
  4. Received: from vm.uni-c.dk by danpost2.uni-c.dk (5.65c+/1.34)
  5.     id AA15375; Wed, 4 Sep 1991 00:04:03 GMT
  6. Message-Id: <199109040004.AA15375@danpost2.uni-c.dk>
  7. Received: from vm.uni-c.dk by vm.uni-c.dk (IBM VM SMTP V2R1) with BSMTP id 0815;
  8.    Wed, 04 Sep 91 02:05:47 DNT
  9. Received: from SEARN.SUNET.SE by vm.uni-c.dk (Mailer R2.07) with BSMTP id 5755;
  10.  Wed, 04 Sep 91 02:05:45 DNT
  11. Received: from SEARN.BITNET by SEARN.SUNET.SE (Mailer R2.05) with BSMTP id
  12.  0515; Wed, 04 Sep 91 02:07:34 +0200
  13. Date:         Tue, 3 Sep 1991 17:01:01 U
  14. Reply-To: Multi-byte Code Issues <ISO10646@JHUVM.BITNET>
  15. Sender: Multi-byte Code Issues <ISO10646@JHUVM.BITNET>
  16. From: Mark Davis <mark_davis@gateway.qm.apple.com>
  17. Subject:      ATM C Implementation
  18. X-To:         unicore@Eng.Sun.COM, ISO10646%JHUVM.BITNET@cunyvm.cuny.edu,
  19.               ansix3l2%JHUVM.BITNET@cunyvm.cuny.edu
  20. To: Multiple recipients of list ISO10646 <ISO10646@JHUVM>
  21. X-Charset: US-DK
  22. X-Char-Esc: 29
  23. Status: RO
  24.  
  25.                        Subject:                               Time:4:34 PM
  26.   OFFICE MEMO          ATM C Implementation                   Date:9/3/91
  27. Here is an implementation of the ATM algorithm, for those interested.
  28. Any feedback would be welcome.--Mark
  29.  
  30. /////////////////////////////////////////////////////////////////
  31. // A Transformation Method
  32. // Author:    Mark Davis
  33. // Date:    August 30, 1991
  34. // The following is a C test implementation of the ATM algorithm
  35. // described in the C0 committee report (see that text for
  36. // details as to the purpose and requirements).
  37. // The details of the algorithm are somewhat changed from that
  38. // report, to correct some bugs and take into account some
  39. // results of the WG2 meeting.
  40. /////////////////////////////////////////////////////////////////
  41.  
  42. #include <STDIO.H>
  43. #include <TYPES.h>
  44.  
  45. typedef unsigned char ubyte;
  46. typedef unsigned short ushort;
  47. typedef unsigned long ucs;
  48. typedef short index;
  49. typedef short bufferLength;
  50. enum {false,true};
  51. typedef unsigned char Boolean;
  52.  
  53. #define c0Start 0x00
  54. #define c0End    0x20
  55. #define g0Start 0x21
  56. #define g0End    0x7E
  57. #define c1Start 0x7F
  58. #define c1End    0x9F
  59. #define g1Start 0xA0
  60. #define g1End    0xFF
  61. #define uStart    0x100
  62.  
  63. #define g0Count (c1Start - g0Start)
  64. #define g1Count (uStart  - g1Start)
  65. #define c0Count (g0Start - c0Start)
  66. #define c1Count (g1Start - c1Start)
  67.  
  68. #define gCount    (g0Count + g1Count)
  69. #define cCount    (c0Count + c1Count)
  70.  
  71. #define section0 0x000000A0
  72. #define section1 0x00000100
  73. #define section2 0x00004016
  74. #define section3 0x00038E2E
  75. #define section4 0xFFFFFFFF
  76.  
  77. #define break0    0xA0
  78. #define break1    0xA1
  79. #define break2    0xF6
  80. #define break3    0xFC
  81. #define break4    0x100
  82.  
  83. #define errorChar 0xFFFFFFFF
  84.  
  85. /////////////////////////////////////////////////////////////////
  86. // SkipTable is used to map a contiguous range onto values that
  87. // do not include control bytes.
  88. // It maps the values from 0 to 256 as follows:
  89. //    0                ..    g0Count-1            =>    g0Start..g0End
  90. //    g0Count            ..    gCount-1            =>    g1Start..g1End
  91. //    gCount            ..    gCount+c0Count-1    =>    c0Start..c0End
  92. //    gCount+c0Count    ..    g1End                =>    c1Start..c1End
  93. // UnskipTable reverses the effect of SkipTable.
  94. // The last two ranges are not, strictly speaking, necessary,
  95. // but make it injective and surjective, providing
  96. // predictability for out-of-range cases.
  97. // Call FillSkipTable before using any other routine.
  98. /////////////////////////////////////////////////////////////////
  99.  
  100. ubyte    SkipTable [256];
  101. ucs        UnskipTable [256];
  102.  
  103. void FillSkipTables (void) {
  104.     index    c;
  105.     for (c = 0; c < 256; c++) {
  106.         if (c < g0Count)
  107.             SkipTable[c] = (ubyte)(c + g0Start);
  108.         else if (c < gCount)
  109.             SkipTable[c] = (ubyte)(c - g0Count + g1Start);
  110.         else if (c < (gCount + c0Count))
  111.             SkipTable[c] = (ubyte)(c - gCount + c0Start);
  112.         else
  113.             SkipTable[c]
  114.                 = (ubyte)(c - (gCount + c0Count) + c1Start);
  115.         UnskipTable[SkipTable[c]] = c;
  116.     };
  117. };
  118.  
  119. /////////////////////////////////////////////////////////////////
  120. // The procedure ToATM takes a UCS character (0..4G) and maps it
  121. // to a sequence of bytes that do not include control characters
  122. // (C0 or C1), SPACE, or DEL.
  123. // The length of the sequence can be from 1 to 5 bytes, depending
  124. // on the first byte.
  125. /////////////////////////////////////////////////////////////////
  126.  
  127. void ToAtm(ucs ch, ubyte* a, bufferLength *len) {
  128.     ubyte *chPtr;
  129.     chPtr = a;
  130.     if (ch < section0) {
  131.         chPtr += (*len = 1);
  132.         *--chPtr = (ubyte) ch;
  133.     } else if (ch < section1) {
  134.         chPtr += (*len = 2);
  135.         *--chPtr = (ubyte) ch;
  136.         *--chPtr = break0;
  137.     } else if (ch < section2) {
  138.         chPtr += (*len = 2);
  139.         ch -= section1;
  140.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  141.         *--chPtr = (ubyte)(break1 + ch);
  142.     } else if (ch < section3) {
  143.         chPtr += (*len = 3);
  144.         ch -= section2;
  145.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  146.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  147.         *--chPtr = (ubyte)(break2 + ch);
  148.     } else {
  149.         chPtr += (*len = 5);
  150.         ch -= section3;
  151.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  152.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  153.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  154.         *--chPtr = SkipTable[ch % gCount]; ch /= gCount;
  155.         *--chPtr = (ubyte)(break3 + ch);
  156.     };
  157. };
  158.  
  159. /////////////////////////////////////////////////////////////////
  160. // The procedure FromATM takes a sequence of ATM bytes (as
  161. // generated by ToATM) and maps it to the UCS character (0..4G)
  162. // that generated it.
  163. // Note that there are a number of byte sequences that cannot
  164. // be produced by the ATM algorithm, and are invalid input.
  165. // As written, this procedure checks for some of the obvious
  166. // invalid values, such as insufficient bufferLength (based on
  167. // the first byte), but does not do full-fledged checking for
  168. // invalid sequences (such as <A0,21>).
  169. /////////////////////////////////////////////////////////////////
  170.  
  171. ucs FromAtm(ubyte** bufferStart, bufferLength maxLength) {
  172.     register ubyte        c, *a;
  173.     ucs                    result;
  174.  
  175.     if (maxLength < 1) return errorChar;
  176.     a = *bufferStart;
  177.     c = *a++;
  178.     result = 0;
  179.     if (c < break0) {
  180.         result = c;
  181.     } else if (c < break1) {
  182.         result = *a++;
  183.     } else if (c < break2) {
  184.         if (maxLength < 2) return errorChar;
  185.         result = c - break1;
  186.         result *= gCount; result += UnskipTable[*a++];
  187.         result += section1;
  188.     } else if (c < break3) {
  189.         if (maxLength < 3) return errorChar;
  190.         result = c - break2;
  191.         result *= gCount; result += UnskipTable[*a++];
  192.         result *= gCount; result += UnskipTable[*a++];
  193.         result += section2;
  194.     } else {
  195.         if (maxLength < 5) return errorChar;
  196.         result = c - break3;
  197.         result *= gCount; result += UnskipTable[*a++];
  198.         result *= gCount; result += UnskipTable[*a++];
  199.         result *= gCount; result += UnskipTable[*a++];
  200.         result *= gCount; result += UnskipTable[*a++];
  201.         result += section3;
  202.     };
  203.     *bufferStart = a;    // pass back new starting point
  204.     return result;
  205. };
  206.  
  207.